package com.hotel.common.user.service.impl;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotel.common.param.UserVipAdd;
import com.hotel.common.user.entity.Vip;
import com.hotel.common.user.entity.VipOrder;
import com.hotel.common.user.mapper.VipMapper;
import com.hotel.common.user.mapper.WalletMapper;
import com.hotel.common.user.service.VipOrderService;
import com.hotel.common.user.service.VipService;
import com.hotel.common.user.service.WalletService;
import com.hotel.common.util.JwtUtil;
import com.hotel.common.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * vip用户表 服务实现类
 * </p>
 *
 * @author KK
 * @since 2024-06-14
 */
@Service
public class VipServiceImpl extends ServiceImpl<VipMapper, Vip> implements VipService {

    @Autowired
    private WalletMapper walletMapper;
    @Autowired
    private VipOrderService vipOrderService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private VipMapper vipMapper;

    @Override
    public R walletPay(UserVipAdd userVipAdd) {
        // 1.查询用户余额
        /*Wallet wallet = walletMapper.selectById(userVipAdd.getUserId());
        if (wallet.getMoney() < userVipAdd.getMoney() * 100) {
            return R.fail("余额不足");
        }*/
        //2.创建订单表
        VipOrder vipOrder = vipOrderService.createOrder(userVipAdd);

        //3.更新用户余额
        walletService.updateMoney(userVipAdd.getUserId(), userVipAdd.getMoney());
        //4.修改会员订单状态
        vipOrder.setStatus(2);
        vipOrderService.updateById(vipOrder);
        //5.判断是新购买vip还是续费vip
        boolean flag = buyOrRenewVip(userVipAdd);
        if (flag){
            return R.ok("会员开通成功");
        }
        return R.ok("会员开通成功");
    }

    @Override
    public R selectVipByToken(String token) {
        if (token == null || token.isEmpty()) {
            return R.fail("无效的token");
        }

        Integer id = parseIdFromToken(token);
        if (id == null) {
            return R.fail("无法从token中解析ID");
        }

        Vip vip = vipMapper.selectOne(new QueryWrapper<Vip>().eq("user_id", id));
        if (vip == null) {
            return R.fail("不是vip");
        }

        return R.ok(vip);
    }
    private Integer parseIdFromToken(String token) {
        JwtUtil jwtUtil = new JwtUtil();
        // 这里假设JwtUtil.parseToken返回的是NumberWithFormat类型，并且可以从中提取id
        // 注意：这里你需要根据JwtUtil的实际返回类型和id的提取方式进行调整
        NumberWithFormat numberWithFormat = (NumberWithFormat) jwtUtil.parseToken(token, "id");
        if (numberWithFormat == null) {
            return null;
        }
        return numberWithFormat.intValue();
    }

    private boolean buyOrRenewVip(UserVipAdd userVipAdd) {
        //1.查询当前的用户是否已经开通vip
        QueryWrapper<Vip> vipQueryWrapper = new QueryWrapper<>();
        vipQueryWrapper.eq("user_id", userVipAdd.getUserId());

        Vip vip = vipMapper.selectOne(vipQueryWrapper);
        //如果没有查询到有开通vip，那么将创建一个vip
        if (vip == null) {
            vip = new Vip();
            vip.setUserId(userVipAdd.getUserId());
            vip.setType(userVipAdd.getVipType());
            vip.setSdate(new Date());
            vip.setDays(365);
            vip.setInfo("开通VIP");
            //结束时间
            Calendar calendar = Calendar.getInstance();//当前是时间
            calendar.add(Calendar.DAY_OF_MONTH, 365);
            Date eDate = calendar.getTime();
            vip.setEdate(eDate);
            int i = vipMapper.insert(vip);
            if (i > 0) {
                return true;
            }

        } else {
            //判断是否已经过期
            if (vip.getEdate().getTime() < System.currentTimeMillis()) {
                // vip已经过期了
                vip.setDays(365);
                vip.setSdate(new Date());
                Calendar calendar = Calendar.getInstance();//当前是时间
                calendar.add(Calendar.DAY_OF_MONTH, 365);
                Date eDate = calendar.getTime();//得到一年后的今天
                vip.setEdate((eDate));
            } else {
                //vip没有过期
                //已经有vip，续费vip
                Calendar calendar = Calendar.getInstance();//设置为原有会员卡的结束时间再加365
                calendar.setTime(vip.getEdate());//原来的过期时间
                calendar.add(Calendar.DAY_OF_MONTH, 365);
                Date eDate = calendar.getTime();//得到 再加一年后的今天
                long betweenDay = DateUtil.between(new Date(), vip.getEdate(), DateUnit.DAY);
                vip.setDays((int) (betweenDay + 365));
                vip.setEdate(eDate);
            }
            int i = vipMapper.updateById(vip);
            if (i > 0) {
                return true;
            }

        }
        return false;

    }


    // 每天凌晨执行一次的任务（例如0点）
    @Scheduled(cron = "0 0 0 * * ?") // 每天的0点0分0秒执行
    public void updateVipExpirationDates() {
        // 创建一个查询构造器
        QueryWrapper<Vip> vipQueryWrapper = new QueryWrapper<>();
        // 设置查询条件，查询今天及之前到期的VIP（需要转换为Date类型）
        // 假设Edate是VIP实体类中表示到期日期的字段
        Date tomorrow = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000); // 明天的日期
        vipQueryWrapper.le("edate", tomorrow); // 小于等于明天的日期

        // 执行查询
        List<Vip> vips = vipMapper.selectList(vipQueryWrapper);

        for (Vip vip : vips) {
            // 注意：这里不需要检查vip.getEdate().isAfter(LocalDate.now())，因为查询条件已经过滤了
            // 转换为LocalDate进行日期操作（如果需要的话）
            // 但由于Edate是Date类型，我们可以直接使用Calendar来减少一天
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(vip.getEdate());
            calendar.add(Calendar.DATE, -1); // 减少一天
            vip.setEdate(calendar.getTime()); // 设置新的日期到Vip对象

            // 更新到数据库
            vipMapper.updateById(vip);
        }
    }
}
